﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using ASBCC.Database.Entity;
using ASBCC.Database.Service;
using SourceCode.Workflow.Client;

namespace ASBCC.Workflow.K2Manager
{
    public class DrawbackActionHandler : ActionHandlerBase
    {
        #region Constructor

        public DrawbackActionHandler(SerializableDictionary dataFields, K2AppForm appForm, K2WorkItem workItem, K2ActionInfo actionInfo) :
            base(dataFields, appForm, workItem, actionInfo, string.Empty, null, null)
        {
            Flow_ActionRecordTableEntity lastActionRecord = K2DataHelper.GetLastActionRecord(workItem.ProcInstId);
            bool canDrawback = CanDrawback(lastActionRecord);
            if (!canDrawback) return;
            _lastActionRecordId = lastActionRecord.ActionRecordID ?? Guid.Empty;

            ProcessInstanceStatus procInstStatus = K2DataHelper.GetProcessInstanceStatus(workItem.ProcInstId);
            bool valid = CheckProcessInstanceStatus(procInstStatus);
            if (!valid) return;
            _processInstanceStatus = procInstStatus;

            PreBuild(lastActionRecord);
        }

        #endregion

        #region Help Methods

        private Guid _lastActionRecordId;
        private ProcessInstanceStatus _processInstanceStatus;

        private bool CanDrawback(Flow_ActionRecordTableEntity lastActoinRecord)
        {
            if (lastActoinRecord == null) return false;
            int ownerId = lastActoinRecord.OwnerID ?? 0;
            string actionType = lastActoinRecord.ActionType;
            if (actionType != K2ActionType.Approve && actionType != K2ActionType.Reject && actionType != K2ActionType.Review)
            {
                throw new Exception("The action type of last step is not allowed to drawback.");
            }
            if (this.AppForm.CurrentUser.UserId != ownerId)
            {
                throw new Exception("The owner of last step to drawback should be current user.");
            }
            return true;
        }

        private bool CheckProcessInstanceStatus(ProcessInstanceStatus procInstStatus)
        {
            if (procInstStatus == ProcessInstanceStatus.Error)
            {
                throw new Exception(string.Format("Process Instance is error. procInstId={}", procInstStatus));
            }
            if (procInstStatus == ProcessInstanceStatus.Active || procInstStatus == ProcessInstanceStatus.Running)
            {
                return true;
            }
            throw new Exception(string.Format("Process Instance is completed, stoped or deleted. procInstId={0}", procInstStatus));
        }

        private void PreBuild(Flow_ActionRecordTableEntity lastActionRecord)
        {
            if (lastActionRecord == null) return;
            WorkItem.ProcInstId = lastActionRecord.ProcInstID ?? 0;
            WorkItem.ArrvialDate = lastActionRecord.ActionDate.Value;

            string toActivityName = lastActionRecord.ActivityName;

            int actualOwnerId = K2Helper.GetActualOwnerId(lastActionRecord.OwnerID ?? 0, lastActionRecord.DelegateFromID ?? 0);

            AuditDestination = new K2AuditDestination(toActivityName, new int[] { actualOwnerId });
        }

        #endregion

        #region Override Methods
        /// <summary>
        /// 当执行回退动作时，重载该方法为GotoActivity
        /// </summary>
        protected override void ExcuteAction()
        {
            GotoActivity(WorkItem.ProcInstId);
        }

        /// <summary>
        /// DrawBack动作时,重载图章生成方法,清除撤回操作的图章
        /// </summary>
        protected override void BuildProcessStamp()
        {
            K2DataHelper.DisableProcessStampByActionRecordId(_lastActionRecordId);
        }

        /// <summary>
        /// Drawback动作时,重载Comment生成方法,清除撤回操作的Comment
        /// </summary>
        protected override void BuildProcessComment()
        {
            K2DataHelper.DisableProcessCommentByActionRecordId(_lastActionRecordId);
        }

        protected override void SendMail()
        {
            string actionType = GetActionType();
            string ApplicationNameEn = FlowProcess.ProcDisplayEn;
            string ApplicationNameCn = FlowProcess.ProcDisplayCn;

            Flow_ProcessMailConfigTableEntity mailConfig = K2DataHelper.GetProcessMailConfig(WorkItem.ProcName, WorkItem.ActivityName, actionType);
            if (mailConfig == null) return;

            EZVisitApplicationTableEntity entity = EZVisitApplicationManager.SelectByKeys(AppForm.FormId);
            if (entity == null) return;

            // 通知下一步审批人
            if (NewMyActivityList != null && NewMyActivityList.Count > 0)
            {
                foreach (MyActivityTableEntity myActivity in NewMyActivityList)
                {
                    if (myActivity.OwnerID == K2User.TempUser) continue; //临时用户不需要通知

                    int toAuditorTemplate = mailConfig.ToAuditorTemplate ?? 0;
                    if (toAuditorTemplate <= 0) continue;

                    EmployeeTableEntity ownerInfo = K2DataHelper.GetUserInfoById(myActivity.OwnerID ?? 0);

                    if (!CheckMailApproverRule(ownerInfo)) continue;

                    string[] mailAddressArr = new string[] { ownerInfo.Email };
                    NameValueCollection collection = new NameValueCollection();
                    collection["{EnglishName}"] = myActivity.OwnerEn;
                    collection["{SerialNumber}"] = myActivity.ApplicationNo;
                    collection["{Applicant}"] = myActivity.ApplicantEn;


                    collection["{SubmitterEN}"] = entity.RequesterNameEN;
                    collection["{SubmitterCN}"] = entity.RequesterNameCN;
                    collection["{ContactNameEN}"] = entity.SomeoneElseNameEN;
                    collection["{ContactNameCN}"] = entity.SomeoneElseNameCN;
                    collection["{CustomerCompany}"] = entity.Company;
                    collection["{TotalCustomers}"] = entity.NumberOfPerson;
                    var startDate = entity.RequestedDateFrom;
                    var endDate = entity.RequestedDateTo;

                    if (startDate != null && endDate != null)
                        collection["{VisitDate}"] = string.Format("From {0} To {1}", startDate.Value.ToShortDateString(), endDate.Value.ToShortDateString());
                    else
                        collection["{VisitDate}"] = string.Empty;
                    if (entity.TotalCost != null)
                        collection["{VisitCost}"] = entity.TotalCost.Value.ToString();
                    else
                        collection["{VisitCost}"] = string.Empty;


                    collection["{FormURL}"] = myActivity.FormURL;
                    collection["{ApplicationNameEn}"] = ApplicationNameEn;
                    collection["{ApplicationNameCn}"] = ApplicationNameCn;
                    collection["{ModuleName}"] = AppForm.ModuleName;

                    NameValueCollection titleCollection = new NameValueCollection();
                    titleCollection["{ApplicationNameEn}"] = ApplicationNameEn;
                    titleCollection["{SerialNumber}"] = myActivity.ApplicationNo;

                    MailService.MailSender(mailAddressArr, toAuditorTemplate, collection, titleCollection);
                }
            }

            // 通知Applicant/Creator
            int toApplicantTemplate = mailConfig.ToApplicantTemplate ?? 0;
            if (toApplicantTemplate > 0)
            {
                EmployeeTableEntity applicantInfo = null;
                EmployeeTableEntity creatorInfo = null;
                if (AppForm.Applicant.UserId > 0)
                {
                    applicantInfo = K2DataHelper.GetUserInfoById(AppForm.Applicant.UserId);
                }
                if (AppForm.Creator.UserId > 0 && AppForm.Creator.UserId != AppForm.Applicant.UserId)
                {
                    creatorInfo = K2DataHelper.GetUserInfoById(AppForm.Creator.UserId);
                }

                string auditUser = (AppForm.DelegateFrom.UserId <= 0 || AppForm.DelegateFrom.UserId == AppForm.CurrentUser.UserId) ?
                    AppForm.CurrentUser.UserEn : string.Format("{0}({1})", AppForm.CurrentUser.UserEn, AppForm.DelegateFrom.UserEn);


                if (CheckMailApplicantRule(applicantInfo))
                {

                    string[] mailAddressArr = new string[] { applicantInfo.Email };
                    NameValueCollection collection = new NameValueCollection();
                    collection["{EnglishName}"] = applicantInfo.NameCN;
                    collection["{SerialNumber}"] = AppForm.ApplicationNo;
                    collection["{AuditUser}"] = auditUser;
                    collection["{AuditTime}"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    collection["{FormURL}"] = DataFields[K2Consts.DataField_Key_FormURL].ToString();
                    collection["{ApplicationNameEn}"] = ApplicationNameEn;
                    collection["{ApplicationNameCn}"] = ApplicationNameCn;
                    collection["{ModuleName}"] = AppForm.ModuleName;
                    collection["{Applicant}"] = AppForm.Applicant.UserEn;

                    NameValueCollection titleCollection = new NameValueCollection();
                    titleCollection["{ApplicationNameEn}"] = ApplicationNameEn;
                    titleCollection["{SerialNumber}"] = AppForm.ApplicationNo;

                    MailService.MailSender(mailAddressArr, toApplicantTemplate, collection, titleCollection);
                }

                if (CheckMailApplicantRule(creatorInfo))
                {
                    string[] mailAddressArr = new string[] { creatorInfo.Email };
                    NameValueCollection collection = new NameValueCollection();
                    collection["{EnglishName}"] = creatorInfo.NameCN;
                    collection["{SerialNumber}"] = AppForm.ApplicationNo;
                    collection["{AuditUser}"] = auditUser;
                    collection["{AuditTime}"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    collection["{FormURL}"] = DataFields[K2Consts.DataField_Key_FormURL].ToString();
                    collection["{ApplicationNameEn}"] = ApplicationNameEn;
                    collection["{ApplicationNameCn}"] = ApplicationNameCn;
                    collection["{ModuleName}"] = AppForm.ModuleName;
                    collection["{Applicant}"] = AppForm.Applicant.UserEn;

                    NameValueCollection titleCollection = new NameValueCollection();
                    titleCollection["{ApplicationNameEn}"] = ApplicationNameEn;
                    titleCollection["{SerialNumber}"] = AppForm.ApplicationNo;

                    MailService.MailSender(mailAddressArr, toApplicantTemplate, collection, titleCollection);
                }
            }
        }

        protected override string GetActionType()
        {
            return K2ActionType.Drawback;
        }

        #endregion
    }
}
